﻿/*! @file
********************************************************************************
<PRE>
文 件 名    : CSProjFile.cs
说    明    : 转换 CSPROJ项目文件
--------------------------------------------------------------------------------
备    注    : VisualStudio2008.CSharp
--------------------------------------------------------------------------------
修改记录: 
 * 日    期    版  本     修改人    修改内容 
 * 2009-7-9    0.1.0     汪泽然    完成基本转换功能
 * 2009.8.4    0.1.1     汪泽然    选择节点前先判断是否找到该节点
 * 2009.8.13   0.1.2     汪泽然    完善项目文件的转换
</PRE>
********************************************************************************
* 版权所有(c) 2008 ~ 2009, 汪泽然, 保留所有权利
*******************************************************************************/
using System;
using System.Xml;
using System.Text;
using System.Xml.XPath;
using Wangzeran.Transform.Core.ITransform;
using Wangzeran.Transform.Core.TransformException;
using System.IO;
using System.Collections.Generic;
using Wangzeran.Transform.Core.Support;

namespace Wangzeran.Transform.PlugIn.VisualStudio2008.CSharp
{
    /// <summary>
    /// 转换 CSPROJ项目文件
    /// </summary>
    public class CSProjFile : BaseProjFile
    {

        #region Common Properties

        /// <summary>
        /// 当前的项目文件版本
        /// </summary>
        protected override string CURRENT_VERSION
        {
            get 
            {
                return "9.0.30729";
            }
        }

        #endregion


        #region BaseProjFile成员

        /// <summary>
        /// 转换项目文件
        /// </summary>
        /// <param name="filePath">项目文件完整路径</param>
        /// <returns>True：转换成功 False：转换失败</returns>
        /// <exception cref="TransformFailureException">转换失败的异常</exception>
        public override bool Transform(string filePath)
        {
            XmlDocument doc = null;
            try
            {
                if (!File.Exists(filePath))
                {
                    return false;
                }
                doc = new XmlDocument();
                doc.Load(filePath);

                XmlNamespaceManager manager = new XmlNamespaceManager(doc.NameTable);
                manager.AddNamespace("ms", COMMON_XMLNAMESPACE);

                #region XPath

                //// 项目配置文件的编码为UTF-8
                //using (XmlTextWriter tr = new XmlTextWriter(filePath, Encoding.UTF8))
                //{
                //    try
                //    {
                //        XPathNavigator nav = doc.CreateNavigator();
                //        XmlNamespaceManager manager = new XmlNamespaceManager(nav.NameTable);
                //        manager.AddNamespace("ms", COMMON_XMLNAMESPACE);

                //        XPathNodeIterator iter = nav.Select("/ms:Project", manager);
                //        if (iter.MoveNext())
                //        {
                //            // 添加 ToolsVersion 属性，值为 3.5
                //            if (iter.Current.GetAttribute("ToolsVersion", manager.DefaultNamespace) == null)
                //            {
                //                iter.Current.CreateAttribute(null, "ToolsVersion", manager.DefaultNamespace, "3.5");
                //            }
                //        }
                //        // 添加IDE版本信息
                //        iter = nav.Select("/ms:Project/ms:PropertyGroup/ms:ProductVersion", manager);
                //        if (iter.MoveNext())
                //        {
                //            iter.Current.SetValue(CURRENT_VERSION);
                //        }

                //        iter = nav.Select("/ms:Project/ms:PropertyGroup", manager);
                //        if (iter.MoveNext())
                //        {
                //            // 添加项目升级标记
                //            iter.Current.AppendChildElement("", "FileUpgradeFlags", COMMON_XMLNAMESPACE, "");
                //            // 添加升级备份路径
                //            iter.Current.AppendChildElement("", "UpgradeBackupLocation", COMMON_XMLNAMESPACE, "");
                //        }
                //    }
                //    finally
                //    {
                //        tr.Formatting = Formatting.Indented;
                //        doc.WriteContentTo(tr);
                //    }
                //}

                #endregion

                if (doc.ChildNodes.Count == 0)
                {
                    throw new TransformFailureException("非法的项目文件");
                }

                XmlNode rootNode = doc.SelectSingleNode("/ms:Project", manager);
                CheckSelectSignleNode(rootNode, "Project");

                if (rootNode.Attributes["ToolsVersion"] == null)
                {
                    XmlAttribute attr = doc.CreateAttribute("ToolsVersion");
                    rootNode.Attributes.InsertBefore(attr, rootNode.Attributes[0]);
                }
                rootNode.Attributes["ToolsVersion"].Value = "3.5";

                XmlNode groupNode = 
                    rootNode.SelectSingleNode("/ms:Project/ms:PropertyGroup", manager);
                CheckSelectSignleNode(groupNode, "PropertyGroup");
                //
                XmlElement targetFrameworkVersion = 
                    doc.CreateElement("TargetFrameworkVersion",COMMON_XMLNAMESPACE);
                targetFrameworkVersion.InnerText = "v2.0";
                //
                XmlElement fileAligment =
                    doc.CreateElement("FileAlignment", COMMON_XMLNAMESPACE);
                fileAligment.InnerText = "512";
                
                groupNode.AppendChild(targetFrameworkVersion);
                groupNode.AppendChild(fileAligment);

                XmlNode productVersion =
                    groupNode.SelectSingleNode("/ms:Project/ms:PropertyGroup/ms:ProductVersion", manager);
                CheckSelectSignleNode(productVersion, "ProductVersion");
                productVersion.InnerText = CURRENT_VERSION;

                XmlNode importNode = 
                    rootNode.SelectSingleNode("/ms:Project/ms:Import", manager);
                CheckSelectSignleNode(importNode, "Import");

                importNode.Attributes["Project"].Value = 
                    @"$(MSBuildToolsPath)\Microsoft.CSharp.targets";

                XmlTextWriter tr = new XmlTextWriter(filePath, Encoding.UTF8);
                tr.Formatting = Formatting.Indented;
                
                doc.Save(tr);

                tr.Close();

                return true;
            }
            catch (Exception ex)
            {
                throw new TransformFailureException(filePath, ex.Message);
            }
        } 

        #endregion


        /// <summary>
        /// 初始化要获取的附属文件实现类集合
        /// </summary>
        /// <param name="lstInterface"></param>
        protected override void InitChildFileInterfaces(IList<IChildFile> lstInterface)
        {
            lstInterface.Add(new SubFiles.CSFile());
            lstInterface.Add(new SubFiles.WebConfigFile());
        }

        /// <summary>
        /// 检查通过XPath获取的节点是否存在
        /// </summary>
        /// <param name="node">节点</param>
        /// <param name="nodeName">节点名称</param>
        private void CheckSelectSignleNode(XmlNode node, string nodeName)
        {
            if (node == null)
            {
                throw new TransformFailureException(
                    String.Format("非法的项目文件， 未找到节点'{0}'", nodeName));
            }
        }
    }
}
